using System.Windows.Forms;
using NUnit.Framework;
using ShadeTree.Binding.Elements;

namespace ShadeTree.Binding.Tests
{
    [TestFixture]
    public class VisibilityAndEnabledBindingTester
    {
        private VisibilityAndEnabledTarget _form;
        private ScreenBinder<VisibilityTarget> _binder;

        [SetUp]
        public void SetUp()
        {
            _form = new VisibilityAndEnabledTarget();
            _form.Show();

            _binder = new ScreenBinder<VisibilityTarget>();
            
        }

        [TearDown]
        public void TearDown()
        {
            _form.Dispose();
        }

        [Test]
        public void BindAndCheckTheVisibilityOfASingleElement()
        {
            var element = new ScreenElement<TextBox>(_form.TextBox1);
            Accessor accessor = ReflectionHelper.GetAccessor<VisibilityTarget>(x => x.Visible1);
            element.BindVisibilityTo(accessor);

            element.UpdateDisplayState(new VisibilityTarget() {Visible1 = true});
            _form.TextBox1.Visible.ShouldBeTrue();

            element.UpdateDisplayState(new VisibilityTarget() { Visible1 = false });
            _form.TextBox1.Visible.ShouldBeFalse();

            element.UpdateDisplayState(new VisibilityTarget() { Visible1 = true });
            _form.TextBox1.Visible.ShouldBeTrue();

        }


        [Test]
        public void BindAndCheckTheEnabledPropertyOfASingleElement()
        {
            var element = new ScreenElement<TextBox>(_form.TextBox1);
            Accessor accessor = ReflectionHelper.GetAccessor<VisibilityTarget>(x => x.Enabled1);
            element.BindEnabledTo(accessor);

            element.UpdateDisplayState(new VisibilityTarget() { Enabled1 = true });
            _form.TextBox1.Enabled.ShouldBeTrue();

            element.UpdateDisplayState(new VisibilityTarget() { Enabled1 = false });
            _form.TextBox1.Enabled.ShouldBeFalse();

            element.UpdateDisplayState(new VisibilityTarget() { Enabled1 = true });
            _form.TextBox1.Enabled.ShouldBeTrue();

        }

        [Test]
        public void ScreenBinderHidesAndShowsTheElements()
        {
            var element1 = new ScreenElement<TextBox>(_form.TextBox1);
            element1.BindEnabledTo(ReflectionHelper.GetAccessor<VisibilityTarget>(x => x.Enabled1));
            element1.BindVisibilityTo(ReflectionHelper.GetAccessor<VisibilityTarget>(x => x.Visible1));

            var element2 = new ScreenElement<TextBox>(_form.TextBox2);
            element2.BindEnabledTo(ReflectionHelper.GetAccessor<VisibilityTarget>(x => x.Enabled2));
            element2.BindVisibilityTo(ReflectionHelper.GetAccessor<VisibilityTarget>(x => x.Visible2));

            _binder.AddElement(element1);
            _binder.AddElement(element2);

            var target = new VisibilityTarget(){Enabled1 = true, Enabled2 = true, Visible1 = true, Visible2 = true};
            _binder.BindToModel(target);

            _form.TextBox1.Enabled.ShouldBeTrue();
            _form.TextBox1.Visible.ShouldBeTrue();
            _form.TextBox2.Enabled.ShouldBeTrue();
            _form.TextBox2.Visible.ShouldBeTrue();

            target.Visible1 = false;
            target.Enabled2 = false;
            _binder.UpdateScreen();

            _form.TextBox1.Enabled.ShouldBeTrue();
            _form.TextBox1.Visible.ShouldBeFalse();
            _form.TextBox2.Enabled.ShouldBeFalse();
            _form.TextBox2.Visible.ShouldBeTrue();

        }


        [Test]
        public void ScreenBinderHidesAndShowsTheElements2()
        {
            _binder.Bind(x => x.Visible1).ToVisibilityOf(_form.TextBox1);
            _binder.Bind(x => x.Visible2).ToVisibilityOf(_form.TextBox2);
            _binder.Bind(x => x.Enabled1).ToEnabledOf(_form.TextBox1);
            _binder.Bind(x => x.Enabled2).ToEnabledOf(_form.TextBox2);

            var target = new VisibilityTarget() { Enabled1 = true, Enabled2 = true, Visible1 = true, Visible2 = true };
            _binder.BindToModel(target);

            _form.TextBox1.Enabled.ShouldBeTrue();
            _form.TextBox1.Visible.ShouldBeTrue();
            _form.TextBox2.Enabled.ShouldBeTrue();
            _form.TextBox2.Visible.ShouldBeTrue();

            target.Visible1 = false;
            target.Enabled2 = false;
            _binder.UpdateScreen();

            _form.TextBox1.Enabled.ShouldBeTrue();
            _form.TextBox1.Visible.ShouldBeFalse();
            _form.TextBox2.Enabled.ShouldBeFalse();
            _form.TextBox2.Visible.ShouldBeTrue();

        }
    }

    public class VisibilityTarget
    {
        public bool Visible1 { get; set;}
        public bool Visible2 { get; set;}
        public bool Enabled1 { get; set;}
        public bool Enabled2 { get; set;}
    }
}
